package com.gofaraway.common.exception.v2;

import com.gofaraway.common.util.PlaceholderUtil;

import javax.validation.constraints.NotNull;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 自定义异常的基类
 *
 * @author ChenPeng
 * @Date 2024/7/24 16:26
 */
public class BaseException extends RuntimeException {
    private static final long serialVersionUID = 1894627027372157658L;
    /**
     * 异常信息
     */
    private BaseErrorInfo baseErrorInfo;
    /**
     * 错误信息占位符参数
     */
    protected Map<String, String> placeHolderParams;

    public BaseException(BaseErrorInfo baseErrorInfo) {
        this.baseErrorInfo = baseErrorInfo;
    }

    public BaseException(BaseErrorInfo baseErrorInfo, Throwable cause) {
        super(cause);
        this.baseErrorInfo = baseErrorInfo;
    }

    /**
     * 添加占位符参数
     *
     * @param key   占位符
     * @param value 值
     * @return 当前对象以支持链式调用
     */
    public BaseException withPlaceHolderKey(String key, String value) {
        if (placeHolderParams == null) {
            placeHolderParams = new HashMap<>(4);
        }
        placeHolderParams.put(key, value);
        return this;
    }

    /**
     * 添加占位符参数，占位符默认为数组下标(从0开始) ${1} ${2}
     *
     * @param values 值
     * @return 当前对象以支持链式调用
     */
    public BaseException withPlaceHolderParam(String... values) {
        if (placeHolderParams == null) {
            placeHolderParams = new HashMap<>(4);
        }
        for (int i = 0; i < values.length; i++) {
            placeHolderParams.put(String.valueOf(i), values[i]);
        }
        return this;
    }

    /**
     * 异常友好的提示信息
     */
    public String getErrorMessage() {
        if (baseErrorInfo == null) {
            return "";
        }
        return PlaceholderUtil.parse(baseErrorInfo.getErrorMessageTemplate(), placeHolderParams);
    }

    /**
     * 生成一个新的BaseErrorInfo对象，对errorMessage进行友好提示转换
     */
    public BaseErrorInfo getBaseErrorInfo() {
        return new BaseErrorInfoImpl(baseErrorInfo.getErrorCode(), baseErrorInfo.getErrorMessageTemplate(), placeHolderParams);
    }

    /**
     * 获取占位符参数 map
     *
     * @return 返回的 map 对象不可更改，若没有参数则返回空map
     */
    public @NotNull Map<String, String> getPlaceHolderParams() {
        if (placeHolderParams != null) {
            return Collections.unmodifiableMap(placeHolderParams);
        }
        return Collections.emptyMap();
    }

    public String getErrorCode() {
        if (baseErrorInfo == null) {
            return "";
        }
        return baseErrorInfo.getErrorCode();
    }

    @Override
    public String getMessage() {
        if (baseErrorInfo == null) {
            return "";
        }
        return "[" + baseErrorInfo.getErrorCode() + "]" + ": " + getErrorMessage();
    }
}

